package roborally.Pieces;
import be.kuleuven.cs.som.annotate.*;

/**
 * This is a class of Carriable Pieces that have a weight and possibly a Position on a Board.
 * @invar 	getWeight() >= 0
 * @invar 	The position is valid 
 * 			| Position.isValidPosition(getPosition().getX(), getPosition().getY(), getPosition().getBoard() )
 * @invar 	An item cannot both be owned by a robot and be located on a Board at the same time
 * 			| !(getPosition() != null && exists Robot robot with robot.getInventory().contains(this) )
 * @invar   Each item can only be carried by a single robot
 * 			| sum( robot in set{robot:Robot| robot.getInventory().contains(this)}: 1) <= 1
 * @version 3.0
 * @author 	Bart Opsomer 2de Bachelor Ingenieurswetenschappen Electrotechniek-Computerwetenschappen 
 * 		   	Peter Opsomer 1ste Master Wiskundige IngenieursTechnieken
 */
public abstract class Item extends GamePieceWithoutOrientation {
	// The weight of the Item, not to be modified
	private final int weight;
	/**
	 * Create a new CarriablePiece with a given weight Since weight is implemented totally and weights are positive, we 
	 * use the absolute value.
	 * 
	 * @param weight the modulus of the weight of the new CarriablePiece
	 * @effect| super()
	 * @post  | this.getWeight() == Math.abs(weight)
	 */
	@Raw @Model
	protected Item(int weight) {
		this.weight = Math.abs(weight);
	}
	/**
	 * @return weight of the CarriablePiece in grams
	 */
	@Basic
	public int getWeight() {
		return weight;
	}
	/**
	 * Return a String to be added to the toString()-methods of subclasses. This method is not abstract, but subclasses should overwrite this
	 * method to get a representative name for them in the GUI. This method gives information about the weight and then the position of the CarriablePiece.
	 * 
	 * @return | result.endsWith(" and weight " + getWeight() + super.toString() )
	 */
	@Override
	public String toString(){
		return " and weight " + weight + " g" + super.toString();
	}
	/**
	 * Terminates this Item and removes it from the Board if necessary
	 * @post	This Wall is terminated
	 * 			| new.isTerminated()
	 * @post    The Wall is removed from the Board
	 * 			| ! exists Board board where
	 * 			|		board.getAllItems().contains(new)
	 */
	@Override
	public void terminate() {
		// No Board should contain terminated GamePieces.
		if(getPosition() != null) {
			getPosition().getBoard().removeItem(this);
			// setPosition(null); is already done in Board.removeItem
		}
		super.terminate();
	}
	/**
	 * Use the carriable item, to be overridden by the subclasses
	 * @param robot the robot which uses this item
	 */
	public abstract void use(Robot robot) ;
	

}
